from django.db import models
from django.db.models.functions import Cast
from rest_framework.views import APIView
from rest_framework.response import Response
import logging

from .serializers import NyCodeSerializers,NyCodePostSerializers,NyCodeTypeSerializers
from .models import NyCode,NyCodeType
from utils.pagination import PageNumberPagination
from django.core.cache import cache

logger = logging.getLogger("api")


class NiuYuanCodeView(APIView):
    def get(self, request):
        # 获取链接信息
        query_params = request.query_params  # 获取查询参数
        cache_key = "ny_code_data"
        cached_data = cache.get(cache_key)
        if not cached_data:
            querysets = NyCode.objects.select_related('type').all().order_by("-id")

            # 检查查询参数并构建查询条件
            if 'code' in query_params and query_params['code'].strip():
                code_value = query_params['code']  # 将 code 字段转换为字符串后进行模糊查询

                querysets = querysets.annotate(code_str=Cast('code', output_field=models.CharField())).filter(code_str__icontains=code_value)
            if 'type' in query_params and query_params['type']:
                querysets = querysets.filter(type__id=query_params['type'])  # 查询ID


            ser = NyCodeSerializers(instance=querysets, many=True)
            cached_data = ser.data
            # cache.set(cache_key, cached_data, timeout=60*10)  # 缓存 5 分钟

        # 分页处理
        paginator = PageNumberPagination()
        page = paginator.paginate_queryset(cached_data, request)
        response = paginator.get_paginated_response(page)

        data = {
            "code": 0,
            "msg":"查询成功",
            "data": response.data
        }
        return Response(data)

    def post(self, request):
        ser = NyCodePostSerializers(data=request.data)
        if ser.is_valid():
            ser.save()
            cache.delete("ny_code_data")
            logger.info({'code': 0, 'msg': '添加成功', 'data': ser.data})
            return Response({'code': 0, 'msg': '添加成功', 'data': ser.data})

        else:
            logger.info({'code': 1, 'msg': ser.errors})
            return Response({'code': 1, 'msg': ser.errors})

class NiuYuanCodeDetailView(APIView):
    def get_object(self, pk):
        try:
            return NyCode.objects.get(pk=pk)
        except NyCode.DoesNotExist as e:
            logger.warning(e)
            return None

    def get(self, request, pk, format=None):
        queryset = self.get_object(pk)
        ser = NyCodeSerializers(instance=queryset)
        data = {
            "code": 0,
            "msg": "查询成功",
            "data": ser.data
        }
        return Response(data)

    def put(self, request, pk, format=None):
        """更新指定主键的对象"""
        # 获取对象
        instance = self.get_object(pk)
        if not instance:
            data = {
                'code': 2,
                'msg': "对象不存在"
            }
            logger.info(data)
            return Response(data)

        # 使用序列化器进行数据验证和更新
        serializer = NyCodePostSerializers(instance, data=request.data, partial=True)

        if serializer.is_valid():
            # 保存更新后的数据
            serializer.save()
            cache.delete("ny_code_data")
            data = {
                'code': 0,
                'msg': "更新成功",
                "data": serializer.data
            }
            logger.info(data)
            return Response(data)

        # 如果数据无效，返回错误信息
        data = {
            'code': 1,
            'msg': serializer.errors
        }
        logger.info(data)
        return Response(data)

    def delete(self, request, pk, format=None):
        codeInfo = self.get_object(pk)
        if codeInfo is not None:
            codeInfo.delete()
            cache.delete("ny_code_data")
            data = {'code': 0, 'msg': '删除成功'}
            logger.info(data)
            return Response(data)
        data = {
            'code': 1,
            'msg': '删除失败,未查询到数据'
        }
        logger.info(data)
        return Response(data)

class NiuYuanCodeBatcDelView(APIView):
    """
    批量删除。ss
    请求体应该包含要删除的ID列表，例如 {"ids": [1, 2, 3]}
    """

    def delete(self, request, format=None):
        ids = request.data.get('ids', [])
        if not isinstance(ids, list):
            logger.info({'code':2,'msg':'传入的参数必须是个列表'})
            return Response({'code':2,'msg':'传入的参数必须是个列表'})

        queryset = NyCode.objects.filter(id__in=ids)
        deleted_count, _ = queryset.delete()

        if deleted_count > 0:
            cache.delete("ny_code_data")
            logger.info({'code': 0, 'msg': '删除成功'})
            return Response({'code':0,'msg':'删除成功'})
        else:
            logger.info({'code':1,'msg':'删除失败，未找到要删除的数据'})
            return Response({'code':1,'msg':'删除失败，未找到要删除的数据'})


class NiuYuanCodeTypeView(APIView):
    def get(self, request):
        # 获取链接信息
        query_params = request.query_params  # 获取查询参数
        cache_key = "ny_code_data_type"
        cached_data = cache.get(cache_key)
        if not cached_data:
            querysets = NyCodeType.objects.all()

            # 检查查询参数并构建查询条件
            if 'title' in query_params:
                querysets = querysets.filter(title__contains=query_params['title'])  # 不区分大小写的包含查询


            ser = NyCodeTypeSerializers(instance=querysets, many=True)
            cached_data = ser.data


        # 分页处理
        paginator = PageNumberPagination()
        page = paginator.paginate_queryset(cached_data, request)
        response = paginator.get_paginated_response(page)

        data = {
            "code": 0,
            "msg":"查询成功",
            "data": response.data
        }
        return Response(data)

    def post(self, request):
        ser = NyCodeTypeSerializers(data=request.data)
        if ser.is_valid():
            ser.save()
            logger.info({'code': 0, 'msg': '添加成功', 'data': ser.data})
            return Response({'code': 0, 'msg': '添加成功', 'data': ser.data})

        else:
            logger.info({'code': 1, 'msg': ser.errors})
            return Response({'code': 1, 'msg': ser.errors})

class NiuYuanCodeTypeDetailView(APIView):
    def get_object(self, pk):
        try:
            return NyCodeType.objects.get(pk=pk)
        except NyCodeType.DoesNotExist as e:
            logger.warning(e)
            return None

    def get(self, request, pk, format=None):
        queryset = self.get_object(pk)
        ser = NyCodeTypeSerializers(instance=queryset)
        data = {
            "code": 0,
            "msg": "查询成功",
            "data": ser.data
        }
        return Response(data)

    def put(self, request, pk, format=None):
        """更新指定主键的对象"""
        # 获取对象
        instance = self.get_object(pk)
        if not instance:
            data = {
                'code': 2,
                'msg': "对象不存在"
            }
            logger.info(data)
            return Response(data)

        # 使用序列化器进行数据验证和更新
        serializer = NyCodeTypeSerializers(instance, data=request.data, partial=True)

        if serializer.is_valid():
            # 保存更新后的数据
            serializer.save()
            cache.delete("ny_code_data")
            data = {
                'code': 0,
                'msg': "更新成功",
                "data": serializer.data
            }
            logger.info(data)
            return Response(data)

        # 如果数据无效，返回错误信息
        data = {
            'code': 1,
            'msg': serializer.errors
        }
        logger.info(data)
        return Response(data)

    def delete(self, request, pk, format=None):
        codeInfo = self.get_object(pk)
        if codeInfo is not None:
            codeInfo.delete()
            cache.delete("ny_code_data")
            data = {'code': 0, 'msg': '删除成功'}
            logger.info(data)
            return Response(data)
        data = {
            'code': 1,
            'msg': '删除失败,未查询到数据'
        }
        logger.info(data)
        return Response(data)

